/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tpdisenio2009.model.dao;

import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import tpdisenio2009.Tpdisenio2009App;
import tpdisenio2009.model.HibernateUtils;
import tpdisenio2009.model.beans.FantasyTeam;
import tpdisenio2009.model.beans.FantasyTeamPlayer;
import tpdisenio2009.model.beans.SoccerPlayer;
import tpdisenio2009.model.beans.TournamentDate;
import tpdisenio2009.model.beans.User;

/**
 *
 * @author Pablito
 */
public class FantasyTeamPlayerDAO extends AbstractDAO<FantasyTeamPlayer> {

    @Override
    public Class<FantasyTeamPlayer> getPersistentClass() {
        return FantasyTeamPlayer.class;
    }

    public List<FantasyTeamPlayer> getFantasyTeamsPlayersByDate( FantasyTeam fantasyTeam, TournamentDate date ) {
        Session session = HibernateUtils.getCurrentSession();

        Criteria mainCriteria = session.createCriteria( FantasyTeamPlayer.class );
        mainCriteria.add( Restrictions.eq( "fantasyTeam", fantasyTeam ) );        
        mainCriteria.add( Restrictions.or( Restrictions.isNull( "endDate" ), Restrictions.ge( "endDate", date.getBanDate() ) ) );
        mainCriteria.add( Restrictions.le( "beginDate", date.getBanDate() ) );

        return mainCriteria.list();
    }

    public void setEndDate(SoccerPlayer player) {
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        try {
            Query query = session.createQuery( "update FantasyTeamPlayer set endDate = :date where soccerPlayer = :player and endDate = null" );
            query.setDate( "date", new Date() );
            query.setEntity( "player", player );
            query.executeUpdate();
            transaction.commit();
        } catch(HibernateException ex) {
            transaction.rollback();
            throw ex;
        } finally {
            session.close();
        }
    }

    public void updatePlayers(List<SoccerPlayer> players) {        

        Session session = HibernateUtils.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        try {
            int c = 0;            
            for (SoccerPlayer player : players) {
                c++;
                if (!isCurrentPlayer( player ) ) {                    
                    FantasyTeamPlayer ftp = new FantasyTeamPlayer();
                    ftp.setBeginDate(new Date());
                    ftp.setFantasyTeam( ((User)Tpdisenio2009App.loggedUser).getFantasyTeam() );
                    ftp.setRol(c < 11 ? FantasyTeamPlayer.TITULAR_ROLE : FantasyTeamPlayer.SUBSTITUTE_ROLE);
                    ftp.setSoccerPlayer(player);
                    session.persist( ftp );
                }
            }
            transaction.commit();
        } catch(HibernateException ex) {
            transaction.rollback();
            throw ex;
        } finally {
            session.close();
        }
    }

    public void updateLineUpPlayers(List<SoccerPlayer> players) {

        Session session = HibernateUtils.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        try {            
            for (SoccerPlayer player : players) {            
                if (!isCurrentPlayer( player ) ) {
                    FantasyTeamPlayer ftp = new FantasyTeamPlayer();
                    ftp.setBeginDate(new Date());
                    ftp.setFantasyTeam( ((User)Tpdisenio2009App.loggedUser).getFantasyTeam() );
                    ftp.setRol(FantasyTeamPlayer.TITULAR_ROLE);
                    ftp.setSoccerPlayer(player);
                    session.persist( ftp );
                }
            }
            transaction.commit();
        } catch(HibernateException ex) {
            transaction.rollback();
            throw ex;
        } finally {
            session.close();
        }
    }

    public void updateSubstitutePlayers(List<SoccerPlayer> players) {

        Session session = HibernateUtils.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        try {
            for (SoccerPlayer player : players) {
                if (!isCurrentPlayer( player ) ) {
                    FantasyTeamPlayer ftp = new FantasyTeamPlayer();
                    ftp.setBeginDate(new Date());
                    ftp.setFantasyTeam( ((User)Tpdisenio2009App.loggedUser).getFantasyTeam() );
                    ftp.setRol(FantasyTeamPlayer.SUBSTITUTE_ROLE);
                    ftp.setSoccerPlayer(player);
                    session.persist( ftp );
                }
            }
            transaction.commit();
        } catch(HibernateException ex) {
            transaction.rollback();
            throw ex;
        } finally {
            session.close();
        }
    }

    private boolean isCurrentPlayer(SoccerPlayer player) {
        Session session = HibernateUtils.getCurrentSession();

        Criteria mainCriteria = session.createCriteria( FantasyTeamPlayer.class );
        mainCriteria.add( Restrictions.eq( "fantasyTeam", ((User)Tpdisenio2009App.loggedUser).getFantasyTeam() ) );
        mainCriteria.add( Restrictions.eq( "soccerPlayer", player ) );
        mainCriteria.add( Restrictions.isNull( "endDate" ) );

        return mainCriteria.uniqueResult() != null;
    }

    public void updateSwapPlayers( FantasyTeamPlayer player, FantasyTeamPlayer substitute ) throws HibernateException {
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        try {

            Date newDate = new Date();

            player.setEndDate( newDate );
            substitute.setEndDate( newDate );
            session.merge( player );
            session.merge( substitute );
            
            FantasyTeamPlayer newTitular = new FantasyTeamPlayer();
            newTitular.setBeginDate( newDate );
            newTitular.setFantasyTeam( substitute.getFantasyTeam() );
            newTitular.setRol( substitute.getRol() );
            newTitular.setSoccerPlayer( player.getSoccerPlayer() );
            session.persist( newTitular );

            FantasyTeamPlayer newSuplente = new FantasyTeamPlayer();
            newSuplente.setBeginDate( newDate );
            newSuplente.setFantasyTeam( player.getFantasyTeam() );
            newSuplente.setRol( player.getRol() );
            newSuplente.setSoccerPlayer( substitute.getSoccerPlayer() );
            session.persist( newSuplente );
            
            transaction.commit();
        } catch(HibernateException ex) {
            transaction.rollback();
            throw ex;
        } finally {
            session.close();
        }
    }

}
